/* eslint-disable no-async-promise-executor */
/**
 * @description: 文件处理
 * @version: 0.0.1
 * @author: xiech
 * @Date: 2023-06-12 18:16:39
 */

import { extname } from 'path';
import { Provide, Inject } from '@midwayjs/core';
import fs = require('fs');
const path = require('path');
import { URL } from 'url';
import { Config } from '@midwayjs/decorator';
import { HttpService } from '@midwayjs/axios';
const uuid = require('node-uuid');
const awaitWriteStream = require('await-stream-ready').write;

@Provide()
export class FileUtils {
  @Config('tempfile')
  tempfile: any;

  @Inject()
  httpService: HttpService;


  /** 
   * @description: 下载文件
   * @param {string} url
   * @param {string} name
   * @return {*}
   */
  async fileUrlUpload(url: string, name: string): Promise<string> {
    return new Promise(async (resolve, reject) => {
      try {
        const fileType = await this.getFileType(url);
        if (fileType) {
          // 处理资源存储本地地址
          const pathName = name || uuid.v4();
          const localPath = this.tempfile + '/' + pathName + fileType;

          this.httpService.get(url, {
            responseType: 'stream', // 设置响应类型为流
          }).then(response => {

            const writer = fs.createWriteStream(localPath);
            response.data.pipe(writer);

            writer.on('finish', () => {
              resolve(localPath);
            });

            writer.on('error', err => {
              reject(err);
            });

          }).catch(error => {
            reject(error);
          });
        } else {
          reject('Not support the fileType');
        }
      } catch (err) {
        reject(err);
      }
    })
  }

  /**
 * 流形式，写文件
 *
 * @param {stream} 资源stream
 * @param {name} 资源名称
 * @returns {localPath} 本地目录
 */
  async fileStreamUpload(stream: any, name: string): Promise<string> {
    const fileType = path.extname(stream.filename);
    // 处理资源存储本地地址
    const pathName = name || uuid.v4();
    const localPath = this.tempfile  + '/' + pathName + fileType;
    // 写为临时文件
    const writeStream = fs.createWriteStream(localPath);
    await awaitWriteStream(stream.data.pipe(writeStream));
    return localPath;
  }

  /** 
   * @description: 获取文件类型
   * @param {string} url 文件URL地址
   * @return {*}
   */
  async getFileType(url: string): Promise<string> {
    const supportType = {
      '.jpg': true,
      '.png': true,
      '.amr': true,
      '.aac': true,
      '.xlsx': true,
      '.js': true,
      '.json': true,
    };
    const myurl = new URL(url);
    const fileType = extname(myurl.pathname);
    if (supportType[fileType]) {
      return fileType;
    }
  }

  /** 
   * @description: 写文件
   * @param {any} data 
   * @param {string} dir
   * @return {*}
   */
  async fsWriteFile(data: any, dir: string): Promise<any> {
    return new Promise((resolve, reject) => {
      fs.writeFile(dir, data, (err: any) => {
        if (err) {
          reject(err);
        } else {
          resolve('ok');
        }
      });
    });
  }

  /** 
   * @description: 删除文件
   * @param {string} dir 文件路径
   * @return {*}
   */
  async deleteFile(dir: string): Promise<any> {
    fs.unlinkSync(dir);
  }

  /** 
   * @description: 读取文件
   * @param {string} dir 文件路径
   * @param {any} format 编码格式
   * @return {*}
   */
  async readFile(dir: string, format: any = 'utf8'): Promise<any> {
    return fs.readFileSync(dir, format);
  }
}